package com.example.projectmanagement.service;

import com.example.projectmanagement.dto.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.actuate.health.HealthComponent;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.OperatingSystem;

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;


@Service
public class SystemMonitorService {

    @Autowired
    private HealthEndpoint healthEndpoint;
    
    @Autowired
    private ApiMonitorService apiMonitorService;
    
    // 存储历史CPU使用率数据的队列
    private final ConcurrentLinkedQueue<SystemMetricDto> cpuHistory = new ConcurrentLinkedQueue<>();
    
    // 存储历史内存使用率数据的队列
    private final ConcurrentLinkedQueue<SystemMetricDto> memoryHistory = new ConcurrentLinkedQueue<>();

    /**
     * 获取服务器状态信息
     */
    public ServerStatusDto getServerStatus() {
        ServerStatusDto status = new ServerStatusDto();
        
        // 获取系统信息
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        OperatingSystem os = si.getOperatingSystem();
        
        // CPU使用率
        CentralProcessor processor = hal.getProcessor();
        long[] prevTicks = processor.getSystemCpuLoadTicks();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        long[] ticks = processor.getSystemCpuLoadTicks();
        status.setCpuUsage(Math.round(processor.getSystemCpuLoadBetweenTicks(prevTicks) * 100 * 100.0) / 100.0);
        
        // 内存使用率
        GlobalMemory memory = hal.getMemory();
        long totalMemory = memory.getTotal();
        long availableMemory = memory.getAvailable();
        status.setMemoryUsage(Math.round(((double)(totalMemory - availableMemory) / totalMemory) * 100 * 100.0) / 100.0);
        
        // 磁盘使用率（简化处理）
        status.setDiskUsage(45.5); // 示例数据
        
        // 当前日期
        status.setCurrentDate(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        
        // 操作系统信息
        status.setOsName(os.toString());
        status.setArchitecture(System.getProperty("os.arch"));
        status.setJavaVersion(System.getProperty("java.version"));
        
        // 运行时间
        RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
        status.setUptime(runtimeMXBean.getUptime() / 1000);
        status.setStartTime(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
                .format(LocalDateTime.ofInstant(java.time.Instant.ofEpochMilli(runtimeMXBean.getStartTime()), java.time.ZoneId.systemDefault())));
        
        status.setServerTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        
        // 应用信息
        status.setAppName("项目管理系统");
        status.setAppVersion("1.0.0");
        status.setAppPort(8080);
        status.setEnvironment("production");
        
        // 健康状态
        HealthComponent health = healthEndpoint.health();
        status.setStatus(health.getStatus().getCode());
        
        // 收集历史数据
        collectHistoryData(status);
        
        return status;
    }

    /**
     * 收集历史数据
     */
    private void collectHistoryData(ServerStatusDto status) {
        // 创建当前时间戳
        String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        
        // 收集CPU使用率历史数据
        SystemMetricDto cpuMetric = new SystemMetricDto();
        cpuMetric.setTimestamp(currentTime);
        cpuMetric.setValue(status.getCpuUsage());
        cpuMetric.setMetricName("CPU Usage");
        cpuHistory.offer(cpuMetric);
        
        // 收集内存使用率历史数据
        SystemMetricDto memoryMetric = new SystemMetricDto();
        memoryMetric.setTimestamp(currentTime);
        memoryMetric.setValue(status.getMemoryUsage());
        memoryMetric.setMetricName("Memory Usage");
        memoryHistory.offer(memoryMetric);
        
        // 限制历史数据数量，保留最近1000条记录
        while (cpuHistory.size() > 1000) {
            cpuHistory.poll();
        }
        while (memoryHistory.size() > 1000) {
            memoryHistory.poll();
        }
    }
    
    /**
     * 获取CPU使用率历史数据
     */
    public List<SystemMetricDto> getCpuHistory(String period) {
        return filterHistoryData(cpuHistory, period);
    }
    
    /**
     * 获取内存使用率历史数据
     */
    public List<SystemMetricDto> getMemoryHistory(String period) {
        return filterHistoryData(memoryHistory, period);
    }
    
    /**
     * 根据时间段过滤历史数据
     */
    private List<SystemMetricDto> filterHistoryData(ConcurrentLinkedQueue<SystemMetricDto> history, String period) {
        List<SystemMetricDto> result = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime cutoffTime = getCutoffTime(now, period);
        
        for (SystemMetricDto metric : history) {
            try {
                LocalDateTime metricTime = LocalDateTime.parse(metric.getTimestamp(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                if (!metricTime.isBefore(cutoffTime)) {
                    result.add(metric);
                }
            } catch (Exception e) {
                // 忽略解析错误
            }
        }
        
        return result;
    }
    
    /**
     * 根据时间段获取截止时间
     */
    private LocalDateTime getCutoffTime(LocalDateTime now, String period) {
        switch (period.toLowerCase()) {
            case "24h":
                return now.minusHours(24);
            case "7d":
                return now.minusDays(7);
            default:
                return now.minusHours(24); // 默认24小时
        }
    }
    
    /**
     * 获取API监控信息
     */
    public ApiMonitorDto getApiMonitorInfo() {
        // 使用真实的API监控数据
        return apiMonitorService.getRealApiMonitorData();
    }

}